home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
vp2_409e.szh
/
FASTSCAN.C
< prev
next >
Wrap
Text File
|
1991-08-22
|
25KB
|
794 lines
/*
$Header: fastscan.c 3.32 87/12/31 15:01:04 Bob Exp $
The Conference Mail System
This module was originally written by Bob Hartman
Sysop of FidoNet node 1:132/101
Spark Software, 427-3 Amherst St, CS 2032, Suite 232, Nashua, NH 03061
The Conference Mail System is a complete Echomail processing package. It
is a superset of the original Echomail utilities created by Jeff Rush, and
also contains ideas gleaned from the ARCmail, Renum, oMMM, MGM, and Opus
programs that were created by various software authors.
This program source code is being released with the following provisions:
1. You are free to make changes to this source code for use on your own
machine, however, altered source files may not be distributed without the
consent of Spark Software.
2. You may distribute "patches" or "diff" files for any changes that you
have made, provided that the "patch" or "diff" files are also sent to Spark
Software for inclusion in future releases of the entire package. A "diff"
file for the source archives may also contain a compiled version, provided
it is clearly marked as not being created from the original source code.
No other executable versions may be distributed without the consent of
Spark Software.
3. You are free to include portions of this source code in any program you
develop, providing: a) Credit is given to Spark Software for any code that
may is used, and b) The resulting program is free to anyone wanting to use
it, including commercial and government users.
4. There is NO technical support available for dealing with this source
code, or the accompanying executable files. This source code is provided
as is, with no warranty expressed or implied (I hate legalease). In other
words, if you don't know what to do with it, don't use it, and if you are
brave enough to use it, you're on your own.
Spark Software may be contacted by modem at (603) 888-8179 (node 1:132/101)
on the public FidoNet network, or at the address given above.
To use this code you will need Microsoft C version 4.0, and also Microsoft
Macro Assembler version 4.0.
*/
/*
$Log: fastscan.c $
* Revision 4.09d 91/06/11 GJS
* Update for to include statistics and logging
*
* Revision 3.32 87/12/31 15:01:04 Bob
* Fixed bug dealing with -O not setting cur_dir
*
* Revision 3.31 87/12/31 14:54:30 Bob
* Fixed bug in -I switch usage
*
* Revision 3.3 87/12/12 00:42:02 Bob
* Source code release
*
*/
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <process.h>
#include "fastecho.h"
#if STATS
#include "stats.h"
#endif
#define DEBUG 0
extern char *REV;
extern char *NAME;
extern SEACONFIG config;
extern AREAS_PTR areas[];
extern char board_name[], sysop_name[];
extern int tot_areas;
extern char bbsfile[];
extern char *arc_cmd[];
extern int nread;
extern int arc_args;
extern int last_msg;
extern int high_one;
extern int convert;
extern struct tm *t2;
extern struct _stamp cur_stamp;
extern int *msg_nums;
extern char *holder1;
extern int f_file;
extern int mail_low, mail_high;
extern int seen_byl;
extern int to_netmail;
extern PACKED p_msg;
extern PKTHDR pkt_hdr;
extern char cur_dir[];
extern char pkt_dir[];
extern unsigned int def_attr;
extern int seahome;
extern int priv_net;
extern int boss_net, boss_node;
extern int opus_1;
extern int cminternal;
extern int msgs_done;
extern char tearline[];
extern char originline[];
extern char seen_byline[];
extern int max_msgs;
extern char abbsfile[];
extern int ctrla;
extern int seen_aka;
extern int only_arc;
extern int noprivate;
extern int noforward;
extern int tiny_seen;
extern int notquiet;
extern int send_pvt;
extern int hwptr;
extern int do_path;
extern char *SEENBYSTR;
extern char *PATHSTR;
extern int path_nets[];
extern int path_nodes[];
extern int tot_path;
extern PW_PTR pw[];
extern int num_pw;
extern int tot_scanned;
extern WBUFFER wbuffs[];
extern int scan_file;
extern int arc_compat;
extern char tmpjunk[];
extern char *noareasbbs;
void fastscan (int argc,char *argv[])
{
/* int i, j, k, l, exit_code, ctla, sbl; */
int i, j, k, l, exit_code;
long t1, t1a, t1b;
char buff1[20], buff2[20];
FILE *ifile;
#if STATS
LogBegin ("Export");
#endif
ifile = NULL;
printf ("Exporting Messages from Conference Mail System:\n\n");
seen_aka = 2;
holder1 = malloc ((unsigned) (NUMBLOCKS*1024 + sizeof (MSG)));
if (holder1 == NULL)
{
printf ("Could not malloc() message space, aborting\n");
exit (2);
}
msg_nums = (int *) malloc ((unsigned) (NUMMSGS * sizeof (int)));
if (msg_nums == NULL)
{
printf ("Could not malloc() message number space, aborting\n");
free (holder1);
exit (2);
}
if (get_sea_config (&config) == -1)
{
if (get_fido_config (&config) == -1)
{
#if STATS
LogExit(2);
#else
exit (2);
#endif
}
}
tot_scanned = 0;
if (argc > 1)
{
if ((argv[1][0] != '-') && (argv[1][0] != '/'))
{
strcpy (abbsfile, argv[1]);
++argv;
--argc;
}
else
{
printf (noareasbbs);
strcpy (abbsfile, "AREAS.BBS");
}
while ((argc > 1) && ((argv[1][0] == '-') || (argv[1][0] == '/')))
{
++argv;
--argc;
switch (argv[0][1])
{
case 'A':
case 'a':
to_netmail = 0;
arc_args = 0;
if (argc > 1)
{
while (--argc)
{
arc_cmd[arc_args++] = argv[1];
++argv;
}
}
break;
case 'B':
case 'b':
arc_compat = 0;
break;
case 'C':
case 'c':
def_attr |= MSGCRASH;
break;
case 'D':
case 'd':
strcpy (cur_dir, argv[1]);
if (cur_dir[strlen(cur_dir)-1] != '\\')
strcat (cur_dir, "\\");
--argc;
++argv;
seahome = 0;
break;
case 'F':
case 'f':
#if STATS
if ((ifile = fopen (argv[1], "rb")) == NULL)
{
printf(LogMessage(1, "Cannot open '%s' for input - exiting\n", argv[1]));
LogExit(2);
}
#else
if ((ifile = fopen (argv[1], "r")) == NULL)
{
printf ("Cannot open '%s' for input - exiting\n", argv[1]);
exit (2);
}
#endif
--argc;
++argv;
break;
case 'G':
case 'g':
do_path = 0;
break;
case 'H':
case 'h':
def_attr |= MSGHOLD;
break;
case 'I':
case 'i':
cminternal = 1;
break;
case 'K':
case 'k':
ctrla = 1;
break;
case 'M':
case 'm':
max_msgs = atoi (argv[1]);
++argv;
--argc;
break;
case 'N':
case 'n':
if ((argv[0][2] == 'p') || (argv[0][2] == 'P'))
{
noprivate = 1;
break;
}
else if ((argv[0][2] == 'f') || (argv[0][2] == 'F'))
{
noforward = 1;
break;
}
break;
case 'O':
case 'o':
opus_1 = 1;
to_netmail = 0;
strcpy (pkt_dir, argv[1]);
if (pkt_dir[strlen(pkt_dir)-1] != '\\')
strcat (pkt_dir, "\\");
strcpy (cur_dir, argv[1]);
if (cur_dir[strlen(cur_dir)-1] != '\\')
strcat (cur_dir, "\\");
--argc;
++argv;
break;
case 'P':
case 'p':
strcpy (pkt_dir, argv[1]);
if (pkt_dir[strlen(pkt_dir)-1] != '\\')
strcat (pkt_dir, "\\");
--argc;
++argv;
break;
case 'Q':
case 'q':
notquiet = 0;
break;
case 'R':
case 'r':
send_pvt = 1;
break;
case 'S':
case 's':
seen_aka = atoi (argv[1]) + 1;
++argv;
--argc;
break;
case 'T':
case 't':
tiny_seen = 1;
break;
case '!':
only_arc = 1;
break;
default:
if (isdigit(argv[0][1]))
{
hwptr = atoi (&(argv[0][1]));
if (hwptr < 2)
break;
}
printf ("Don't understand '%s'\n", argv[0]);
(void) fs_usage ();
}
}
if (argc > 1)
{
(void) fs_usage ();
}
}
else
{
printf (noareasbbs);
strcpy (abbsfile, "AREAS.BBS");
}
if (arc_args == 0)
{
#ifndef OS2
arc_args = 3;
if (((arc_cmd[0] = malloc (6)) == NULL) ||
((arc_cmd[1] = malloc (5)) == NULL) ||
((arc_cmd[2] = malloc (2)) == NULL))
#else
arc_args = 2;
if (((arc_cmd[0] = malloc (5)) == NULL) ||
((arc_cmd[1] = malloc (3)) == NULL))
#endif
{
printf ("Out of memory compiling ARC command - exiting\n");
exit (2);
}
#ifndef OS2
strcpy (arc_cmd[0], "PKARC");
strcpy (arc_cmd[1], "-OCT");
strcpy (arc_cmd[2], "A");
#else
strcpy (arc_cmd[0], "ARC2");
strcpy (arc_cmd[1], "A5");
#endif
}
if (((arc_cmd[arc_args] = malloc (80)) == NULL) ||
((arc_cmd[arc_args+1] = malloc (80)) == NULL))
{
printf ("Out of memory compiling ARC command - exiting\n");
exit (2);
}
if (cminternal && (arc_args == 0))
{
printf ("Cannot use -I without -A - exiting\n");
exit (2);
}
sprintf (sysop_name, "Sysop of %d/%d", config.net[1], config.node[1]);
strcpy (board_name, "Unknown Board - Node");
/* Strip out duplicate AKA's */
for (i = 1; i < config.num_addrs; i++)
{
for (j = i+1; j <= config.num_addrs; j++)
{
if ((config.net[i] == config.net[j]) &&
(config.node[i] == config.node[j]))
{
/* Found a duplicate AKA */
for (k = j+1; k <= config.num_addrs; k++)
{
config.net[k-1] = config.net[k];
config.node[k-1] = config.node[k];
}
--config.num_addrs;
break;
}
}
}
/* Save how many are the default */
seen_aka = seen_aka>config.num_addrs?config.num_addrs:seen_aka;
if (compile_areas ((unsigned char *)abbsfile) != 0)
{
#if STATS
printf (LogMessage(1, "Could not process AREAS file\n"));
LogExit(2);
#else
printf ("Could not process AREAS file\n");
exit (2);
#endif
}
/* Now read areas from file if necessary */
if (ifile != NULL)
{
while (fgets (tmpjunk, 200, ifile) != NULL)
{
#if STATS
tmpjunk[strcspn(tmpjunk, "\r")] = 0;
#endif
for (i = 0; i < tot_areas; i++)
{
/* Did we match the name? */
#if STATS
if (stricmp(tmpjunk, areas[i]->area_name) == 0)
#else
if ((strlen(areas[i]->area_name) == strcspn(tmpjunk, "\r"))
&& (strnicmp(tmpjunk, areas[i]->area_name, strlen(areas[i]->area_name)) == 0))
#endif
{
/* Mark as unavailable now, and switch it later */
areas[i]->flags |= NOT_AVAIL;
}
}
}
/* Swap the state of the available flag */
for (i = 0; i < tot_areas; i++)
{
if (areas[i]->flags & NOT_AVAIL)
{
areas[i]->flags &= ~NOT_AVAIL;
}
else
{
areas[i]->flags |= NOT_AVAIL;
}
}
fclose (ifile);
}
/* Now set up the default nodes */
for (i = 0; i < tot_areas; i++)
{
for (j = 1; j <= seen_aka; j++)
{
areas[i]->zone[areas[i]->num_nodes] = config.zone[j];
areas[i]->net[areas[i]->num_nodes] = config.net[j];
areas[i]->node[areas[i]->num_nodes] = config.node[j];
areas[i]->handle[areas[i]->num_nodes] = -1;
areas[i]->aname[areas[i]->num_nodes] = areas[i]->area_name;
#if STATS
areas[i]->msgs_scanned[areas[i]->num_nodes] = 0;
#endif
++areas[i]->num_nodes;
}
sort_em (&(areas[i]->zone[0]), &(areas[i]->net[0]), &(areas[i]->node[0]),
areas[i]->num_nodes, 1, &(areas[i]->handle[0]), &(areas[i]->aname[0]));
}
sscanf (REV, "$%s %s", buff1, buff2);
sprintf (tearline, NAME, buff2);
/* Set up the data for the current time stamp */
t1 = time(NULL);
t2 = localtime (&t1);
cur_stamp.date = ((t2->tm_year - 80)<<9) + ((t2->tm_mon+1)<<5) + t2->tm_mday;
cur_stamp.time = (t2->tm_hour<<11) + (t2->tm_min<<5) + (t2->tm_sec>>1);
/* If we are going to packet, set some extra stuff up */
if (!to_netmail)
{
pkt_hdr.orig_net = config.net[1];
pkt_hdr.orig_node = config.node[1];
pkt_hdr.month = t2->tm_mon;
pkt_hdr.day = t2->tm_mday;
pkt_hdr.year = t2->tm_year;
pkt_hdr.hour = t2->tm_hour;
pkt_hdr.minute = t2->tm_min;
pkt_hdr.second = t2->tm_sec;
pkt_hdr.rate = 0;
pkt_hdr.ver = PKTVER;
pkt_hdr.product = MYPRODUCT;
pkt_hdr.rev_lev = (char) ((REV[11]-'0')*(unsigned)10+(REV[13]-'0'));
for (i = 0; i < 8; i++)
pkt_hdr.password[i] = 0;
for (i = 0; i < 20; i++)
pkt_hdr.extra[i] = 0;
pkt_hdr.pr_data = (long) REV[14];
p_msg.ver = PKTVER;
p_msg.orig_node = config.node[1];
p_msg.orig_net = config.net[1];
p_msg.cost = 0;
}
(void) high_msg (config.mailpath, &mail_high, &mail_low);
printf ("MAIL area '%s' has highest message %d\n", config.mailpath, mail_high);
exit_code = 0;
seen_byline[0] = '\r';
if (!only_arc)
{
for (i = 0; i < tot_areas; i++)
{
/* If we have no nodes to process for this one then skip it */
if ( (areas[i]->num_nodes == seen_aka) &&
(!((areas[i]->flags & ROUTETHRU) || (areas[i]->flags & MAIL_DIR))))
{
continue;
}
if ((areas[i]->flags & MAIL_DIR) && (to_netmail))
{
printf ("Area MAIL_DIR not going to ARCmail - not processed\n");
}
else if ((*(areas[i]->msgs_in_area) == -1) || !(areas[i]->flags & SIBLING))
{
if (!(areas[i]->flags & NOT_AVAIL))
{
create_seen(&seen_byline[1], &(areas[i]->net[0]), &(areas[i]->node[0]),
areas[i]->num_nodes, 1, SEENBYSTR);
if (do_path)
{
seen_byl = strlen (seen_byline);
sprintf (&(seen_byline[seen_byl-2]), "\001PATH: %d/%d\r\n\r\n",
config.net[1], config.node[1]);
seen_byl = strlen (seen_byline);
}
#if DEBUG
printf ("seen_byline = %d chars long and it is \n'%s'\n", strlen(seen_byline), seen_byline);
#endif
make_originline (areas[i]);
exit_code = scan (areas[i]);
}
}
else
{
printf ("Area '%s' already scanned under an alias name\n", areas[i]->area_name);
}
/* Now write null bytes and close open files */
if (!to_netmail)
{
k = i + 1;
for (j = 0; j < areas[i]->num_nodes; j++)
{
if (areas[i]->handle[j] > 0)
{
if ((i < tot_areas - 1) && (exit_code == 0))
{
for (l = 0; l < areas[k]->num_nodes; l++)
{
if ((areas[i]->net[j] == areas[k]->net[l]) &&
(areas[i]->node[j] == areas[k]->node[l]))
{
areas[k]->handle[l] = areas[i]->handle[j];
break;
}
}
if (l < areas[k]->num_nodes)
continue;
}
(void) fast_write (areas[i]->handle[j], "\0\0", 2);
(void) fast_close (areas[i]->handle[j]);
areas[i]->handle[j] = -1;
}
}
}
if (exit_code >= 1)
{
break;
}
}
}
free(holder1);
free((char *) msg_nums);
t1b = time(NULL);
/* Free up our buffer pointers since we don't need them any more */
for (i = 0; i < 20; i++)
{
if (wbuffs[i].wbuff != NULL)
{
_ffree (wbuffs[i].wbuff);
wbuffs[i].wbuff = NULL;
wbuffs[i].wptr = NULL;
wbuffs[i].wsize = -1;
}
}
/* If we have to do the ARCmail, go and do it */
if ((!to_netmail) && ((!opus_1) || cminternal))
{
arc_cmd[arc_args+2] = NULL;
arc_a ();
free (arc_cmd[arc_args]);
free (arc_cmd[arc_args+1]);
}
t1a = time(NULL);
t1a = t1a - t1b;
t1b = t1b - t1;
printf ("\nExporting %d messages created %d outbound messages and took %02ld:", tot_scanned, msgs_done, t1b/3600);
t1b = t1b%3600;
printf ("%02ld:", t1b/60);
t1b = t1b%60;
printf ("%02ld\n", t1b);
if (!to_netmail && !opus_1)
{
printf ("ARCmailing the packets took %02ld:", t1a/3600);
t1a = t1a%3600;
printf ("%02ld:", t1a/60);
t1a = t1a%60;
printf ("%02ld\n", t1a);
}
if (!f_file)
#if STATS
LogExit(exit_code);
#else
exit(exit_code);
#endif
for (i = 0; i < tot_areas; i++)
{
free (areas[i]->msg_path);
free (areas[i]->area_name);
if (!(areas[i]->flags & SIBLING))
free ((char *) areas[i]->msgs_in_area);
free ((char *) areas[i]->net);
free ((char *) areas[i]->node);
free ((char *) areas[i]->handle);
free ((char *) areas[i]->aname);
free ((char *) areas[i]);
}
for (i = 0; i < num_pw; i++)
{
free (pw[i]->password);
free (pw[i]);
}
}
void fs_usage ()
{
#ifdef OS2
printf ("Usage: VP2 EXPORT file -c/h -k -t -d dir -p dir -m max# -n[p/f] -s # -a arccmd\n");
#else
printf ("Usage: VP EXPORT file -c/h -k -t -d dir -p dir -m max# -n[p/f] -s # -a arccmd\n");
#endif /* OS2 */
#ifndef NOHELP
printf (" where file is the filename to use for AREAS.BBS\n");
printf (" -c/h can be either -c for CRASH or -h for HOLD\n");
printf (" -k use the IFNA ^A kludge\n");
printf (" -t use 'tiny' seen-by lines\n");
printf (" -d dir uses directory 'dir' for creating arcmail files\n");
printf (" -p dir uses directory 'dir' for temporary packet files\n");
printf (" -m max# only generate max# messages\n");
printf (" -n[p/f] can be either -np or -nf for not sending private\n");
printf (" messages, or not forwarding messages\n");
printf (" -s # put the first # AKA's into the SEEN-BY list\n");
printf (" -a arccmd executes 'arccmd' as the command for creating the\n");
printf (" ARCmail files.\n");
printf ("Examples:\n");
#ifdef OS2
printf (" VP2 EXPORT MYAREAS.BBS -m 300\n");
printf (" VP2 EXPORT -m 300 -k -s 2\n");
printf (" VP2 EXPORT -d C:\\OPUS -p E:\\TMP -m 300 -a ARC2 A5\n");
#else
printf (" VP EXPORT MYAREAS.BBS -m 300\n");
printf (" VP EXPORT -m 300 -k -s 2\n");
printf (" VP EXPORT -d C:\\OPUS -p E:\\TMP -m 300 -a ARC A\n");
#endif /* OS2 */
#endif /* NOHELP */
exit (2);
}
void make_originline(AREAS_PTR which)
{
char fname[100], msg_str[15], *bname;
int f, i, t;
bname = board_name;
sprintf (fname, "%s\\ORIGIN", which->msg_path);
(void) filedir (fname, 0, msg_str, 0);
if (msg_str[0] != '\0')
{
/* Open file */
if ((f = open (fname, O_RDONLY|O_BINARY)) == -1)
{
for (i = which->num_nodes-1; i >= 0; i--)
{
if (which->handle[i] > 0)
{
break;
}
}
if (i >= 0)
{
(void) fast_write (which->handle[i], "\0\0", 2);
(void) fast_close (which->handle[i]);
which->handle[i] = -1;
f = open (fname, O_RDONLY|O_BINARY);
}
}
if (f != -1)
{
/* read 80 bytes */
t = fast_read (f, fname, 80);
/* close file */
(void) fast_close (f);
/* place \0 at either \r \n ^z or 80 chars */
for (i = 0; i < t; i++)
{
if ((fname[i] == '\r') || (fname[i] == '\n') || (fname[i] == 26))
break;
}
fname[i] = '\0';
bname = fname;
}
}
sprintf (originline, "\r\n%s * Origin: %s (%d:", tearline, bname,
(config.zone[1] != 0)?config.zone[1]:1);
if (boss_net <= 0)
sprintf (&originline[strlen(originline)], "%d/%d)", config.net[1],
config.node[1]);
else
sprintf (&originline[strlen(originline)], "%d/%d.%d)", boss_net,
boss_node, config.node[1]);
#if DEBUG
printf ("Origin line = %d chars long and it is\n'%s'\n", strlen(originline), originline);
#endif
}